'/
' ProjectName
' 
' =========================================================================
' 
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
' 
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
' 
' You should have received a copy of the GNU General Public License
' along with this program.  If not, see <http://www.gnu.org/licenses/>.
'/

include "UI.bmx"

type Video extends Base

	'// -------------------------------------------------------------------------------------------------------------
	'// Screen settings.
	'// -------------------------------------------------------------------------------------------------------------
	global COLOR_BIT_DEPTH:short;
	global REFRESH_RATE:short;
	global RESOLUTION_X:int;
	global RESOLUTION_Y:int;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Screen ids.
	'// -------------------------------------------------------------------------------------------------------------
	global SCR_NONE:byte = 0;
	global SCR_INIT_SOUND:byte = 10;
	global SCR_LOAD_IMAGES:byte = 30;
	global SCR_LOAD_SOUNDS:byte = 31;
	global SCR_LOAD_MENU:byte = 32;
	global SCR_MENU:byte = 50;
	global SCR_GAME_LOOP:byte = 70;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Initialize video mode. This creates the window, sets the default colors, and the blending mode. It also hides
	'// the windows cursor, since the game has its own cursor.
	'// -------------------------------------------------------------------------------------------------------------
	method init(refreshRate:int, screenWidth:int, screenHeight:int)
	
		'// Update all variables that use the resolution etc.
		updateWindowSettings(refreshRate, screenWidth, screenHeight);
		
		'// Set the graphics mode and create the window.
		sConsoleManager.writeLog("Initializing OpenGL.");
		setGraphicsDriver(GLMax2DDriver());
		try
		
			graphics(int(RESOLUTION_X), ..
			         int(RESOLUTION_Y), ..
			             COLOR_BIT_DEPTH, ..
			             REFRESH_RATE);
		
		catch e:object
		
		  sGUI.error("Could not initialize video mode.");
		
		end try
		
		'// Hide the cursor.
		hideMouse();
		
		'// Setup some default color settings.
		sConsoleManager.writeLog("Initializing drawing.");
		setDefaultClsColor();
		setMaskColor(0, 0, 0);
		setColor(0, 0, 0);
		setBlend(ALPHABLEND);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Update video settings.
	'// -------------------------------------------------------------------------------------------------------------
	method updateWindowSettings(refreshRate:int, screenWidth:int, screenHeight:int)
	
		local colorBitDepth:int;
		
		if (sMaster.p_fullscreen) ..
			colorBitDepth = 16; ..
		else ..
			colorBitDepth = 0;
		
		COLOR_BIT_DEPTH = colorBitDepth;
		REFRESH_RATE = refreshRate;
		RESOLUTION_X = screenWidth;
		RESOLUTION_Y = screenHeight;
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Enter a screen.
	'// -------------------------------------------------------------------------------------------------------------
	method enterScreen(id:byte, fade:byte = false)
	
		select (id)
		
			case SCR_NONE
			case SCR_INIT_SOUND
			case SCR_LOAD_IMAGES
			case SCR_LOAD_SOUNDS
			case SCR_LOAD_MENU
			case SCR_MENU
			case SCR_GAME_LOOP
			default
				sGUI.error("Error 18: Invalid screen id '" + id + "'.");
		
		end select
		
		if (fade) ..
			sVideo.fadeOut();
		
		m_curScreen = id;
		
		if (fade) ..
			sVideo.fadeIn();
		
		flushKeys();
		flushMouse();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw a loading screen.
	'// -------------------------------------------------------------------------------------------------------------
	method drawLoadingScreen(id:byte)
	
		'// Fill the screen with black.
		setClsColor(0, 0, 0);
		cls();
		
		'// Set the loading message.
		local message:string;
		select (id)
		
			case SCR_INIT_SOUND
				message = "Initializing OpenAL...";
			case SCR_LOAD_IMAGES
				message = "Loading images...";
			case SCR_LOAD_SOUNDS
				message = "Loading sounds...";
			case SCR_LOAD_MENU
				message = "Loading menu...";
			default
				sGUI.error("Error 19: Not a loading screen id '" + id + "'.");
		
		end select
		
		'// Print the message in the center of the screen.
		drawutil.setColorInit(255, 255, 255);
		drawTextCentered(message);
		
		'// Reset the drawing colors.
		setDefaultClsColor();
		drawutil.resetColor();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw a text centered on screen.
	'// -------------------------------------------------------------------------------------------------------------
	method drawTextCentered(str:string)
	
		drawText(str, RESOLUTION_X shr 1 - textWidth(str) shr 1, RESOLUTION_Y shr 1 - textHeight(str) shr 1);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw a text centered on screen.
	'// -------------------------------------------------------------------------------------------------------------
	method drawTextCenteredX(str:string, y:int)
	
		drawText(str, RESOLUTION_X shr 1 - textWidth(str) shr 1, y);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Set the default CLS (CLear Screen) color.
	'// -------------------------------------------------------------------------------------------------------------
	method setDefaultClsColor()
	
		setClsColor(255, 255, 255);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Fade in from a specific color (black, if no color is specified).
	'// -------------------------------------------------------------------------------------------------------------
	method fadeIn(timeMS:int = 500, r:byte = 0, g:byte = 0, b:byte = 0)
	
		?debug
			return
		?
		
		local a:float;
		local timer:int;
		
		for local frame:int = 1 to timeMS
		
			timer = milliSecs();
			
			cls();
			
			setAlpha(1.0);
			drawFrame();
			
			a = 1.0 - 1.0 / timeMS * float(frame);
			
			setAlpha(a);
			setColor(r, g, b);
			drawRect(0, 0, RESOLUTION_X, RESOLUTION_Y);
			
			flip();
			
			if (milliSecs() = timer) ..
				delay(1);
		
		next
		
		setAlpha(1.0);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Fade out to a specific color (black, if no color is specified).
	'// -------------------------------------------------------------------------------------------------------------
	method fadeOut(timeMS:int = 500, r:byte = 0, g:byte = 0, b:byte = 0)
	
		?debug
			return
		?
		
		local a:float;
		local timer:int;
		
		for local frame:int = 1 to timeMS
		
			timer = getTics();
			
			cls();
			
			setAlpha(1.0);
			drawFrame();
			
			a = 0.0 + 1.0 / timeMS * float(frame);
			
			setAlpha(a);
			setColor(r, g, b);
			drawRect(0, 0, RESOLUTION_X, RESOLUTION_Y);
			
			flip();
			
			if (milliSecs() = timer) ..
				delay(1);
		
		next
		
		setAlpha(0.0);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Render a frame.
	'// -------------------------------------------------------------------------------------------------------------
	method renderFrame()
	
		'// Clear the screen.
		cls();
		
		'// Draw the frame.
		drawFrame();
		
		'// Flip the buffers.
		flip();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw the frame, depending on which screen is active.
	'// -------------------------------------------------------------------------------------------------------------
	method drawFrame()
	
		select (m_curScreen)
		
			case SCR_NONE
			case SCR_INIT_SOUND, ..
			     SCR_LOAD_IMAGES, ..
			     SCR_LOAD_SOUNDS, ..
			     SCR_LOAD_MENU
				drawLoadingScreen(m_curScreen);
			case SCR_MENU
				setClsColor(128, 128, 128);
				cls();
				
				'// Draw the GUI.
				sUI.drawUI();
				
				'// Draw the cursor.
				if (not sConsoleManager.isVisible()) ..
					sUI.drawCursor();
				
				'// Draw the console.
				drawConsole();
				
				'// Reset drawing colors.
				drawutil.resetColor();
				setDefaultClsColor();
			case SCR_GAME_LOOP
				'// Draw the scene.
				drawScene();
				
				'// Draw HUD.
				drawHUD();
				
				'// Draw the console.
				drawConsole();
		
		end select
		
		'// Draw statistics.
		drawStatistics();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw the console, if not hidden.
	'// -------------------------------------------------------------------------------------------------------------
	method drawConsole()
	
		if (sConsoleManager.isVisible()) ..
			sConsoleManager.drawConsole();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw the HUD.
	'// -------------------------------------------------------------------------------------------------------------
	method drawHUD()
	
		'// You can also draw the GUI here too, if you want to create the HUD out of the GUI library, or if you want
		'// an in-game menu as well.
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw statistics.
	'// -------------------------------------------------------------------------------------------------------------
	method drawStatistics()
	
		drawutil.setColorInit(230, 210, 190);
		
		if (sMaster.p_drawFps) ..
			drawText("FPS: " + int(1.0 / sMaster.m_frameTime), 10, 10);
		
		drawutil.resetColor();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Draw the scene.
	'// -------------------------------------------------------------------------------------------------------------
	method drawScene()
	
		'// This is where we draw the world of any graphical game.
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Current screen to render.
	'// -------------------------------------------------------------------------------------------------------------
	field m_curScreen:byte = SCR_NONE;

end type

global sVideo:Video = new Video;
